package com.neelsys.visualisation.service.adapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.data.neo4j.template.Neo4jOperations;

import com.neelsys.visualisation.domain.BaseNodeEntity;
import com.neelsys.visualisation.domain.CourseDesignator;
import com.neelsys.visualisation.domain.EntranceTest;
import com.neelsys.visualisation.domain.MajorCombination;
import com.neelsys.visualisation.domain.ui.JSONGraph;
import com.neelsys.visualisation.domain.ui.JSONLink;
import com.neelsys.visualisation.domain.ui.JSONNode;

public class MajorCombAdapter {

	Neo4jOperations template;

	JSONGraph jsonGraph;

	private MajorCombination majorComb;

	private Map<Long, Integer> nodeMapper = new HashMap<Long, Integer>();

	public MajorCombAdapter(Neo4jOperations template, MajorCombination majorComb) {
		this.majorComb = majorComb;
		this.template = template;
		jsonGraph = new JSONGraph();
	}

	public JSONGraph adaptToJsonGraph() {

		CourseDesignator courseDesignator = template.fetch(majorComb
				.getCourseDesigntator());

		addNodeToGraph(
				jsonGraph,
				createNewNode(courseDesignator.getCourseLevel().name(), "L",
						courseDesignator.getNodeId(), 0L));
		addNodeToGraph(
				jsonGraph,
				createNewNode(majorComb.getMajorIdentifier(), "M",
						majorComb.getNodeId(), 1L));

		createRelationShip(majorComb.getCourseDesigntator(), majorComb,
				jsonGraph);

		NextLevelsAdapter nextLevelsAdapter=new NextLevelsAdapter(this, 1L);
		nextLevelsAdapter.adapt(majorComb);

		return jsonGraph;

	}

	JSONLink createNewLink(Long source, Long target) {
		JSONLink jsonLink = new JSONLink();
		jsonLink.setSource(nodeMapper.get(source));
		jsonLink.setTarget(nodeMapper.get(target));

		return jsonLink;
	}

	JSONNode createNewNode(String name, String nodeType, Long nodeId, Long level) {
		JSONNode jsonNode = new JSONNode();
		jsonNode.setName(name);
		jsonNode.setNodetype(nodeType);
		jsonNode.setNodeId(nodeId);
		jsonNode.setLevel(level);

		return jsonNode;
	}

	void addNodeToGraph(JSONGraph graph, JSONNode node) {
		if (graph.getNodes() == null) {
			graph.setNodes(new ArrayList<JSONNode>());
		}
		if (!nodeMapper.containsKey(node.getNodeId())) {
			graph.getNodes().add(node);
			nodeMapper.put(node.getNodeId(), graph.getNodes().size() - 1);
		}

	}

	void createRelationShip(BaseNodeEntity fromNode, BaseNodeEntity toNode,
			JSONGraph graph) {
		JSONLink link = createNewLink(fromNode.getNodeId(), toNode.getNodeId());
		addLinkToGraph(graph, link);
	}

	void addLinkToGraph(JSONGraph graph, JSONLink link) {
		if (graph.getLinks() == null) {
			graph.setLinks(new ArrayList<JSONLink>());
		}
		graph.getLinks().add(link);
	}

	
}
